﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using GodPl.WorldState;

namespace GodPl.GameObjects
{
    public abstract class GameObject : GodPl.GameObjects.IGameObject
    {
        public World World
        {
            get { return world; }
        }
        protected World world;

        /// <summary>
        /// Returns the position of the origin (center)
        /// </summary>
        public virtual Vector2 Position
        {
            get { return position; }
            set { position = value; }
        }
        protected Vector2 position;


        protected float spriteScale;

        protected Rectangle localBounds;

        public GameObject(World world, Vector2 position)
        {
            this.world = world;
            this.position = position;
        }

        public abstract void LoadContent();

        public abstract void Update(GameTime gameTime);

        public abstract void Draw(GameTime gameTime, SpriteBatch spriteBatch);

        public float DistanceTo(GameObject target)
        {
            return (float)Math.Sqrt(Math.Pow(this.Position.X - target.Position.X, 2) +
                                    Math.Pow(this.Position.Y - target.Position.Y, 2));
        }

        public bool IsAdjacentTo(GameObject target)
        {
            return (DistanceTo(target) <= (this.Radius + target.Radius));
        }

        /// <summary>
        /// Returns whether the object is colliding with any obstacle in the game
        /// </summary>
        /// <returns></returns>
        public bool IsColliding()
        {
            var obstacles = from o in world.GameObjects
                            where (o is IObstacle)
                            select o;

            foreach (GameObject o in obstacles)
            {
                if (this.BoundingRectangle.GetIntersectionDepth(o.BoundingRectangle) != Vector2.Zero)
                {
                    return true;
                }
            }

            return false;

        }

        public virtual Rectangle BoundingRectangle
        {
            get
            {
                int left = (int)Math.Round(Position.X - localBounds.Width/2);
                int top = (int)Math.Round(Position.Y - localBounds.Height/2);
                return new Rectangle(left, top, localBounds.Width, localBounds.Height);
            }
        }


        public virtual float Radius
        {
            get
            {
                Rectangle r = localBounds;
                return ((float)Math.Sqrt(Math.Pow(localBounds.Width, 2) + Math.Pow(localBounds.Height, 2)) / 2);
            }
        }

    }
}
